home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS11.ADF / Modula-2 / CaseConvert / scanner.mod < prev    next >
Text File  |  1986-08-05  |  3KB  |  99 lines

  1. (*    Implementation of a simple scanner.
  2.  
  3.     Created: 5/15/86 by RB
  4.     
  5.     Modified:
  6.  
  7.  
  8.    Copyright (c) 1986 - by Richie Bielak
  9.    
  10.    This program maybe freely copied, but please leave my name in.
  11.    Thanks....Richie
  12.  
  13. *)
  14. IMPLEMENTATION MODULE Scanner;
  15.  
  16. FROM InOut IMPORT Read, Write, Done;
  17.  
  18. VAR
  19.   LastCh : CHAR;
  20.  
  21. (* Get next character from the input, return 0C at EOF *)
  22. PROCEDURE GetChar (VAR ch : CHAR) : CHAR;
  23.   BEGIN
  24.     IF LastCh <> 0C THEN 
  25.       ch := LastCh; LastCh := 0C; 
  26.     ELSE
  27.       Read (ch); IF NOT Done THEN ch := 0C END;
  28.     END;
  29.     RETURN ch
  30.   END GetChar;
  31.  
  32. (* Put a character back in the input stream *)
  33. PROCEDURE PushBack (VAR ch : CHAR);
  34.   BEGIN
  35.     LastCh := ch; ch := 0C;
  36.   END PushBack;
  37.  
  38. (* Get the next token from the input stream *)
  39. PROCEDURE GetToken (VAR Token : TokenType;
  40.                     VAR Value : ARRAY OF CHAR) : BOOLEAN;
  41.   TYPE
  42.     StateType = (Scan, OpenPren, Asterisk, id);
  43.     CharSet   = SET OF CHAR;
  44.   VAR
  45.     State : StateType;
  46.     ch    : CHAR;
  47.     i     : CARDINAL;
  48.     MoreInput : BOOLEAN;
  49.   BEGIN
  50.     State := Scan; i := 0; Token := Null; MoreInput := TRUE;
  51.     (* Do this until we find a token, or hit EOF *)
  52.     WHILE (Token = Null) AND (MoreInput) DO
  53.       (* Get another character from the input *)
  54.       IF GetChar (ch) = 0C THEN MoreInput := FALSE
  55.       ELSE
  56.         CASE State OF
  57.           Scan: IF    ch = '(' THEN     State := OpenPren
  58.               ELSIF ch = '*' THEN    State := Asterisk
  59.             ELSIF ch = '"' THEN    Token := DoubleQ
  60.             ELSIF ch = "'" THEN    Token := SingleQ
  61.             ELSIF CAP(ch) IN CharSet{'A'..'Z'} THEN State := id
  62.             END;
  63.        |
  64.       OpenPren: IF ch = "*" THEN
  65.                   Token := OpenComment
  66.               ELSE
  67.               State := Scan; PushBack (ch)
  68.                     END
  69.       |
  70.       Asterisk: IF ch = ")" THEN
  71.                   Token := CloseComment
  72.                     ELSE
  73.                 State := Scan; PushBack (ch)
  74.                     END
  75.           |
  76.       id: IF CAP (ch) IN CharSet{'A'..'Z', '0'..'9'} THEN
  77.             (* Do nothing *)
  78.           ELSE
  79.             Token := Identifier; PushBack (ch)
  80.               END
  81.         END; (* CASE *)
  82.         (* Output current character, or store in returned value *)
  83.         (* Note: only identifiers are stored.                   *)
  84.         IF (State = id) AND (ch <> 0C) THEN
  85.           Value[i] := ch; INC (i)
  86.         ELSIF ch <> 0C THEN
  87.           Write (ch)
  88.         END (* IF *)
  89.       END (* IF *)
  90.     END; (* WHILE  *)
  91.     (* Mark the end of value with a null *)
  92.     Value [i] := 0C;
  93.     RETURN (Token <> Null)
  94.   END GetToken;
  95.  
  96. BEGIN
  97.   LastCh := 0C;
  98. END Scanner.
  99.